home *** CD-ROM | disk | FTP | other *** search
/ DOOM Companion (Alt) / DOOM Companion CD-ROM - iso.7z / DOOM Companion CD-ROM.iso / other / doom_ps / main.c < prev    next >
C/C++ Source or Header  |  1994-03-08  |  6KB  |  232 lines

  1. /*
  2.  * Doom PostScript map generator. V1.1
  3.  * Copyright James Bonfield, 3/3/94 
  4.  *
  5.  * Options:
  6.  * -d        debugging - displays the wad directory
  7.  * -w wadfile    select another wad file (default "doom.wad")
  8.  * -l level    choose another level (default "E1M1")
  9.  * -o        do not display objects
  10.  * -m        do not display monsters
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "wad.h"
  17.  
  18. /*
  19.  * A4 paper is 8 1/4" by 11 3/4"
  20.  * We allow 1/2" border.
  21.  */
  22. #define PAPER_X (72 * 8.25)
  23. #define PAPER_Y (72 * 11.75)
  24. #define PAPER_BORDER (72 * 0.5)
  25.  
  26. void doit(int fd, struct directory *dir, int size, char *lev_name,
  27.       int objs, int mons);
  28.  
  29. void dump_dir(struct directory *d, int size) {
  30.     int i;
  31.  
  32.     for (i = 0; i < size; i++) {
  33.     printf("Item=%5d, Start=%8d, Len=%8d, Name=%.8s\n",
  34.            i, d[i].start, d[i].length, d[i].name);
  35.     }
  36. }
  37.  
  38.  
  39. void usage() {
  40.     puts("wad [-w wadfile] [-d] [-o] [-m] [-l level]");
  41. }
  42.  
  43. int main(int argc, char **argv) {
  44.     struct directory *d;
  45.     int fd, size, c;
  46.     int objs=1, mons=1, dump=0;
  47.     char *level = "E1M1";
  48.     char *wadfile = "doom.wad";
  49.     extern char *optarg;
  50.     extern int optind;
  51.  
  52.     while ((c = getopt(argc, argv, "domw:l:")) != EOF) {
  53.     switch (c) {
  54.     case 'w': /* wad file */
  55.         wadfile = optarg;
  56.         break;
  57.     case 'd': /* debug */
  58.         dump=1;
  59.         break;
  60.     case 'l': /* select the level */
  61.         level = optarg;
  62.         break;
  63.     case 'o': /* don't display objects */
  64.         objs=0;
  65.         break;
  66.     case 'm': /* don't display monsters */
  67.         mons=0;
  68.         break;
  69.     }
  70.     }
  71.  
  72.     if (optind != argc) {
  73.     usage();
  74.     return 1;
  75.     }
  76.  
  77.     if (NULL == (d = open_wad(wadfile, &fd, &size))) {
  78.     fprintf(stderr, "Failed to open wad file.\n");
  79.     return 1;
  80.     }
  81.  
  82.     if (dump) {
  83.     dump_dir(d, size);
  84.     return 0;
  85.     }
  86.  
  87.     doit(fd, d, size, level, objs, mons);
  88.     
  89.     return 0;
  90. }
  91.  
  92. void doit(int fd, struct directory *dir, int size, char *lev_name,
  93.       int objs, int mons) {
  94.     linedef *linedefs;
  95.     vertex *vertexes;
  96.     blockmap *blocks;
  97.     sidedef *sidedefs;
  98.     sector *sectors;
  99.     thing *things;
  100.     int numline, numvert, numblock, numside, numsect, numthing;
  101.     int lev_index;
  102.     int xorigin, yorigin, xsize, ysize;
  103.     int2 sector;
  104.     double xscale, yscale;
  105.     int i, j;
  106.  
  107.     /* find level index */
  108.     lev_index = get_index(dir, size, lev_name, 0);
  109.     if (lev_index == 0) {
  110.     fprintf(stderr, "Unknown level: %s\n", lev_name);
  111.     exit(1);
  112.     }
  113.  
  114.     /* load relevent arrays for this level */
  115.     linedefs = read_linedefs(fd, dir, size, lev_index, &numline);
  116.     vertexes = read_vertexes(fd, dir, size, lev_index, &numvert);
  117.     blocks   = read_blockmap(fd, dir, size, lev_index, &numblock);
  118.     sidedefs = read_sidedefs(fd, dir, size, lev_index, &numside);
  119.     sectors  = read_sectors (fd, dir, size, lev_index, &numsect);
  120.     things   = read_things  (fd, dir, size, lev_index, &numthing);
  121.  
  122.     /* calculate scaling info */
  123.     xorigin = blocks[0];
  124.     yorigin = blocks[1];
  125.     xsize   = blocks[2] * 0x80;
  126.     ysize   = blocks[3] * 0x80;
  127.  
  128.     xscale = (double)(PAPER_Y - 2*PAPER_BORDER)/xsize;
  129.     yscale = (double)(PAPER_X - 2*PAPER_BORDER)/ysize;
  130.  
  131.     if (xscale > yscale)
  132.     xscale = yscale;
  133.     else
  134.     yscale = xscale;
  135.  
  136.     /* output postscript header */
  137.     printf("%%!\n");
  138.     printf("newpath\n");
  139.     printf("\n");
  140.     printf("1 setlinecap\n");
  141.     printf("%f %f translate\n", PAPER_BORDER, PAPER_Y - PAPER_BORDER);
  142.     printf("-90 rotate\n");
  143.     printf("%f %f scale\n", xscale, yscale);
  144.     printf("%d %d translate\n", -xorigin, -yorigin);
  145.     printf("%f setlinewidth\n", (double).5/xscale);
  146.     printf("\n");
  147.     printf("/l {\n");
  148.     printf("    setgray setlinewidth moveto lineto stroke\n");
  149.     printf("} def\n");
  150.     printf("\n");
  151.     printf("/a {\n");
  152.     printf("    5 0 360 arc stroke\n");
  153.     printf("} def\n");
  154.     printf("\n");
  155.     printf("/m {\n");
  156.     printf("    gsave\n");
  157.     printf("    moveto rotate\n");
  158.     printf("    0 -13 rmoveto\n");
  159.     printf("    0 25 rlineto\n");
  160.     printf("    -10 -10 rlineto\n");
  161.     printf("    10 10 rmoveto\n");
  162.     printf("    10 -10 rlineto\n");
  163.     printf("    stroke\n");
  164.     printf("    grestore\n");
  165.     printf("} def\n");
  166.  
  167.     /*
  168.      * Display the walls.
  169.      * Secret passages are done in grey.
  170.      */
  171.     for (i = 0; i < numline; i++) {
  172.     sector = sidedefs[linedefs[i].sidedef1].sector;
  173.  
  174.     printf("%d %d %d %d ",
  175.            vertexes[linedefs[i].to_vertex].x,
  176.            vertexes[linedefs[i].to_vertex].y,
  177.            vertexes[linedefs[i].from_vertex].x,
  178.            vertexes[linedefs[i].from_vertex].y);
  179.     
  180.     if (linedefs[i].attrib & LI_IMPASS) {
  181.         printf("%f ", 1.2/xscale);
  182.     } else {
  183.         printf("%f ", 0.5/xscale);
  184.     }
  185.  
  186.     if (linedefs[i].attrib & LI_SECRET || sectors[sector].special == 9) {
  187.         printf(".5 l\n");
  188.     } else {
  189.         printf("0 l\n");
  190.     }
  191.     }
  192.  
  193.     /*
  194.      * Do we need to display objects or monsters?
  195.      */
  196.     if (objs || mons) {
  197.  
  198.     printf("    %d setlinewidth\n", 1/xscale);
  199.  
  200.     for (i = 0; i < numthing; i++) {
  201.  
  202.         switch(things[i].type) {
  203.         /* is this a monster? */
  204.         case 7: /* spider */
  205.         case 9: /* sergeant */
  206.         case 16: /* cyber */
  207.         case 58: /* invis */
  208.         case 3001: /* imp */
  209.         case 3002: /* demon */
  210.         case 3003: /* minotaur */
  211.         case 3004: /* human */
  212.         case 3005: /* cacodemon */
  213.         case 3006: /* skull */
  214.         if (mons) {
  215.             printf("%d %d %d m\n",
  216.                things[i].angle, things[i].x, things[i].y);
  217.         }
  218.         break;
  219.         default:
  220.         /* not a monster - so direction isn't important */
  221.         if (objs) {
  222.             printf("%d %d a\n", things[i].x, things[i].y);
  223.         }
  224.         }
  225.     }
  226.     }
  227.  
  228.     puts("showpage");
  229.  
  230.     return;
  231. }
  232.